<template>
  <el-container>
    <el-header style="height: 60px;">
      <div class="header-info">
        <div class="header-item deploy-steps">
          <el-steps :active="deployRec.stage" :process-status="dpProcessStatus" finish-status="success">
            <el-step :title="stepConfigTitle" @click.native="onStepClick(STAGE_CONFIG)">
              <i slot="icon" class="el-icon-loading" />
            </el-step>
            <el-step title="构建镜像" @click.native="onStepClick(STAGE_IMAGE_BUILD)" />
            <el-step :title="stepImageBuildTitle" @click.native="onStepClick(STAGE_IMAGE_BUILD)" />
            <el-step title="创建部署" @click.native="onStepClick(STAGE_DEPLOY)" />
            <el-step :title="stepDeploy" @click.native="onStepClick(STAGE_DEPLOY)" />
          </el-steps>
        </div>
        <div v-if="deployRec.projectId" class="header-item deploy-info">
          服务名称:
          <el-button size="mini" type="text">
            <router-link :to="`/deploy/dpserverdetail?projectId=${deployRec.projectId}`">
              {{ deployRec.projectName }}
            </router-link>
          </el-button>
          部署分支:
          <span style="color: green">
            {{ deployRec.sourceBranch }}
          </span>
        </div>
      </div>
    </el-header>
    <el-main>
      <branch-list-component
        v-if="stage===STAGE_CONFIG"
        :project-id.sync="projectId"
        :deploy-rec.sync="deployRec"
        :deploy-button-loading="deployButtonLoading"
        @deploy="startDeploy"
      />
      <log-content-component
        v-if="stage===STAGE_IMAGE_BUILD||stage===STAGE_IMAGE_BUILD_CHECK"
        ref="imageBuildComponent"
        :log-content="deployRec.buildLog"
        :loading.sync="buildLoading"
      />
      <log-content-component
        v-if="stage===STAGE_DEPLOY||stage===STAGE_DEPLOY_CHECK"
        ref="deployLogComponent"
        :log-content="deployRec.deployLog"
        :loading.sync="deployLoading"
      />
    </el-main>
  </el-container>
</template>

<script>

import { mapGetters } from 'vuex'
import * as APIS from '@/api/server/index'
import branchListComponent from './components/BranchListComponent.vue'
import LogContentComponent from './components/LogContentComponent.vue'
import { Notification } from 'element-ui'
import global_const from '@/mixins/global_const'

export default {
  name: 'Proccess',
  components: {
    branchListComponent,
    LogContentComponent
  },
  mixins: [global_const],
  data() {
    return {
      projectId: -1,

      deployRec: {
        stage: 0
      },

      // 用户点击的阶段
      clickStage: null,

      // 定时器(不同阶段获取不同的数据)
      setIntRequest: null,

      // 观看模式
      readonly: true,

      // 部署按钮状态
      deployButtonLoading: false
    }
  },
  computed: {
    ...mapGetters([
      'env'
    ]),
    dpProcessStatus() {
      if (this.deployRec.deployStatus === this.DEPLOY_STATUS_NONE) {
        return 'wait'
      } else if (this.deployRec.deployStatus === this.DEPLOY_STATUS_RUNNING) {
        return 'process'
      } else if (this.deployRec.deployStatus === this.DEPLOY_STATUS_FAILED) {
        return 'error'
      } else if (this.deployRec.deployStatus === this.DEPLOY_STATUS_SUCCESS) {
        return 'success'
      }

      return 'wait'
    },
    stage() {
      if (this.clickStage !== null) {
        return this.clickStage
      }
      return this.deployRec.stage
    },

    stepConfigTitle() {
      return '部署配置(' + this.getStageStatusTitle(this.STAGE_CONFIG) + ')'
    },
    stepImageBuildTitle() {
      return '构建状态检测(' + this.getStageStatusTitle(this.STAGE_IMAGE_BUILD_CHECK) + ')'
    },
    stepDeploy() {
      return '健康检测(' + this.getStageStatusTitle(this.STAGE_DEPLOY_CHECK) + ')'
    },

    buildLoading() {
      // 如果阶段为构建，状态为进行中，且日志为空
      if (this.deployRec.stage === this.STAGE_IMAGE_BUILD && this.deployRec.deployStatus === this.DEPLOY_STATUS_RUNNING && !this.deployRec.buildLog) {
        return true
      }

      return false
    },
    deployLoading() {
      if (this.deployRec.stage === this.STAGE_DEPLOY && this.deployRec.deployStatus === this.DEPLOY_STATUS_RUNNING && !this.deployRec.deployLog) {
        return true
      }

      return false
    }
  },
  watch: {
  },
  mounted() {
    this.$bus.$on('global-env-change', data => {})

    this.init()
  },
  beforeDestroy() {
    this.$bus.$off('global-env-change')
    this.stopIntRequest()
  },
  methods: {
    init() {
      // 獲取項目關聯的部署模板id（帶著階段列表）
      const query = this.$route.query
      if (query === 'undefined' || query.projectId === 'undefined') {
        this.$notify({
          title: 'url中必须带上projectId参数',
          type: 'error',
          duration: 2500
        })
        return
      }
      this.projectId = parseInt(query.projectId)
      const deployRecId = query.deployRecId
      if (deployRecId === 'undefined' || deployRecId === undefined) {
        this.readonly = false
      } else {
        // 获取部署详情，查看模式
        APIS.queryDeploy({
          id: deployRecId
        }).then(res => {
          this.deployRec = res
        }).finally(() => {
        })
      }
      this.startTimer()
    },
    startDeploy(mergeBranchName) {
      if (this.deployRec.stage === this.STAGE_CONFIG) {
        // 合并分支
        this.onNewDeploy(this.projectId, mergeBranchName)
      }
    },
    getStageStatusTitle(stage) {
      if (stage < this.deployRec.stage) {
        // 比当前步骤少，说明已经成功了
        return '完成'
      } else if (stage === this.deployRec.stage) {
        // 等于当前步骤，根据状态判读
        if (this.deployRec.deployStatus === this.DEPLOY_STATUS_NONE) {
          return '准备'
        } else if (this.deployRec.deployStatus === this.DEPLOY_STATUS_RUNNING) {
          return '进行中'
        } else if (this.deployRec.deployStatus === this.DEPLOY_STATUS_FAILED) {
          return '失败'
        } else if (this.deployRec.deployStatus === this.DEPLOY_STATUS_SUCCESS) {
          return '成功'
        } else if (this.deployRec.deployStatus === this.DEPLOY_STATUS_CANCEL) {
          return '已取消'
        } else {
          return '未知'
        }
      }
      return '未就绪'
    },
    reDeploy() {
      const _this = this
      return APIS.deploy({
        id: _this.deployRec.id
      }).then(res => {
        // 需等待获取结果成功后，进入下一步
        Notification.success({
          title: '部署任务创建成功',
          duration: 5000
        })
        _this.deployRec = res
      }).catch(err => {
        Notification.error({
          title: err,
          duration: 5000
        })
      }).finally(() => {
      })
    },

    onNewDeploy(projectId, branch) {
      const _this = this
      // 创建部署
      this.deployButtonLoading = true
      APIS.createProjectDeploy({
        projectId: this.projectId,
        env: this.env,
        source: branch
      }).then(res => {
        _this.deployRec = res
        this.$router.push(`/deploy/proccess?projectId=${projectId}&deployRecId=${res.id}`)
      }).finally(() => {
        this.deployButtonLoading = false
      })
    },

    startTimer() {
      // 时间事件，
      const _this = this
      this.setIntRequest = setInterval(() => {
        if (_this.deployRec.id) {
          if (this.deployRec.deployStatus === this.DEPLOY_STATUS_FAILED ||
            (this.deployRec.deployStatus === this.DEPLOY_STATUS_SUCCESS &&
              this.deployRec.stage === this.STAGE_DEPLOY_CHECK &&
            this.deployRec.deployLog !== '')) {
            return
          }
          // 获取部署详情
          APIS.queryDeploy({
            id: _this.deployRec.id
          }).then(res => {
            _this.deployRec = res
          }).finally(() => {
          })
        }
      }, 2000) // 每隔10秒 10000ms
    },
    stopIntRequest() {
      this.setIntRequest && clearInterval(this.setIntRequest)
      this.setIntRequest = null // 内存回收
    },

    onStepClick(step) {
      if (this.deployRec.stage <= step) {
        this.clickStage = null
      } else {
        this.clickStage = step
      }
    }
  }
}
</script>

<style lang="scss" scoped>

  /* min-height: calc(100vh - 50px);*/
  .el-footer {
    background-color: #B3C0D1;
    color: #333;
    text-align: center;
    line-height: 60px;
    height: 20%;
  }

  .el-main {
    color: #333;
    text-align: center;
    height: 80%;
    /*line-height: 160px;*/
  }

  .el-container {
    margin-bottom: 0px;
    min-height: calc(100vh - 85px) !important;
  }

  .previous-button {
    margin-top: 5px;
    margin-right: 15px;
    width: 120px;
    height: 50px;
  }

  .header-info {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
  }

  .header-item {
    flex: 1 1 auto;
    margin: 0px;
    margin-top: 2px;
  }

  .deploy-info {
    text-align: right;
    line-height:58px;
    height: 58px;
    font-size: 20px;
    padding-right: 10px;

    .el-button--mini {
      font-size: 20px;
    }
  }
</style>
